# -*- coding: utf-8 -*-
import json
import logging
import re
import functools
from common.abtest import db as abtest_db
from common.cache import account as account_cache
from common.utils.api import get_client_ip
from common.utils.exceptions import PermissionError, ReachLimit

_LOGGER = logging.getLogger(__name__)
INTERNAL_IPS = ['113.57.172.122', '120.26.57.89',
                '120.27.162.212', '121.41.6.238']


def check_user_name_chars(user_name):
    m = re.match(ur'^[0-9a-zA-Z\u4e00-\u9fa5]{1,50}$', user_name)
    if m is None:
        return False
    return True


def is_char_valid_in_username(c):
    m = re.match(ur'^[0-9a-zA-Z\u4e00-\u9fa5]{1,50}$', c)
    if m is None:
        return False
    return True


def validate_username(user_name):
    return ''.join([x for x in user_name if is_char_valid_in_username(x)])


def frequency_limit(func):
    """
    API频率限制

    不知道if False 的原由，又有很多地方引用，暂时不动以前的逻辑，重新写一个
    """

    def _wrapper(req, *args, **kwargs):
        ip = get_client_ip(req)
        if False and ip not in INTERNAL_IPS:
            checked = account_cache.check_ip_pay_limit(ip, req.user_id)
            if not checked:
                _LOGGER.error(
                    'frequency limit, ip:%s, user_id:%s', ip, req.user_id)
                raise PermissionError()
        return func(req, *args, **kwargs)

    return _wrapper


def frequency_limit_v2(code, limit=10):
    """
    API频率限制
    :param code: 唯一的业务编码
    :param limit 每个小时的限制数，默认10
    :return:
    """

    def decorator(func):
        @functools.wraps(func)
        def wrapper(*args, **kw):
            request = args[1]
            ip = get_client_ip(request)
            user_id = request.user_id
            key = "{}:{}".format(code, user_id or ip)
            checked = account_cache.check_frequency_limit(key, limit)
            if not checked:
                raise ReachLimit()
            return func(*args, **kw)

        return wrapper

    return decorator


def check_abtest(user_id, chn, cvc, item):
    if not item.get('abtest'):
        return True
    try:
        abtest_id = item['abtest']
        abtest_item = abtest_db.get_abtest(abtest_id)
        if not abtest_item:
            return True
        abtest_dict = json.loads(abtest_item.content)
        if 'user_id' in abtest_dict:
            if not user_id:
                return False  # 是否对匿名用户开放
            user_id_range = abtest_dict['user_id']
            uid_suffix = str(user_id)[-2:]
            if uid_suffix < user_id_range[0] or uid_suffix > user_id_range[1]:
                return False
        if 'chn' in abtest_dict:
            include = abtest_dict['chn'].get('include', [])
            exclude = abtest_dict['chn'].get('exclude', [])
            if include and chn not in include:
                return False
            if exclude and chn in exclude:
                return False
        if 'cvc' in abtest_dict:
            include = abtest_dict['cvc'].get('include', [])
            exclude = abtest_dict['cvc'].get('exclude', [])
            if include and str(cvc) not in include:
                return False
            if exclude and (cvc) in exclude:
                return False
    except:
        return True
    return True
